package com.xiaocq.wordskiller;

import java.util.Random;
import java.util.TreeSet;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class CompletionTest extends Activity {
	private static final String TAG = "CompletionTest";
	private boolean isUnitTest = false;

	private Button backToMenu, previousWord, nextWord;
	private EditText displayExplain, wordInput;
	private TextView testProgressShow;
	private ProgressDialog progressDialog;

	private Cursor cursor;

	private int mTestCount;
	private int mFinishedCount;

	private boolean isNewTest;
	private int unitId;
	private int mTestType;
	private long allTimeInMillis;

	private int[] details;
	private TreeSet<Integer> checkSet;
	private int nowPosition;
	private String[] nowWords;
	private String explain;
	private int maxNum;
	private Random random;
	private boolean canChange;

	private long startTimeInMillis, finishTimeInMillis;

	private ActivityHelper helper;
	
	private Intent sendIntent;

	private Handler loadingHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			progressDialog.dismiss();
			prepareWord(nowPosition);
		};
	};
	
	private Handler savingHandler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			progressDialog.dismiss();
			startActivity(sendIntent);
			finish();
		};
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.completiontest);

		initComponents();

		Intent intent = getIntent();
		loadOrInit(intent);

	}
	
	@Override
	protected void onDestroy() {
		cursor.close();
		super.onDestroy();
	}

	private void prepareWord(int position) {
		int cursorId = addAndSaveNewCursorId(position);
		cursor.moveToPosition(cursorId);
		explain = cursor.getString(2).replaceAll("\\|", "\n");
		displayExplain.setText(explain);
		wordInput.setText("");

		nowWords = cursor.getString(1).split("/");
		
		mFinishedCount = position + 1;
		freshState();
		startTimeInMillis = System.currentTimeMillis();
	}

	private int addAndSaveNewCursorId(int position) {
		int cursorId = details[position] % 10000;
		if(cursorId != 0) return cursorId;
		do {
			cursorId = random.nextInt(maxNum);
		} while (checkSet.contains(cursorId));
		checkSet.add(cursorId);

		cursor.moveToPosition(cursorId);

		details[position] = cursor.getInt(0) * 100000 + cursorId;

		return cursorId;
	}
	
	private void loadOrInit(Intent intent) {
		isNewTest = intent.getBooleanExtra(CommandList.IS_THE_NEW_TEST, true);
		if (CommandList.COSTUM_COMPLETION_TEST.equals(intent.getAction())) {
			isUnitTest = false;

			mTestType = intent.getIntExtra(CommandList.COSTUM_TEST_TYPE, 0);
			mTestCount = intent
					.getIntExtra(CommandList.COSTUM_TEST_COUNTS, 30);
			mFinishedCount = intent.getIntExtra(
					CommandList.COSTUM_FINISHED_COUNTS, 0);
			allTimeInMillis = intent.getLongExtra(CommandList.COSTUM_TIME_COST, 0L);
			
		} else if (CommandList.UNIT_COMPLETION_TEST.equals(intent.getAction())) {
			isUnitTest = true;

			unitId = intent.getIntExtra(CommandList.UNIT_ID, 1);
			mFinishedCount = intent.getIntExtra(
					CommandList.UNIT_FINISHED_COUNTS, 0);
			allTimeInMillis = intent.getLongExtra(CommandList.UNIT_TIME_COST, 0L);
		}

		random = new Random();

		helper = new ActivityHelper(CompletionTest.this);
		prepareInBackGround();
	}
	
	private void prepareInBackGround() {
		progressDialog = new ProgressDialog(CompletionTest.this);
		progressDialog.setMessage(getText(R.string.tip_loading));
		progressDialog.show();

		new Thread() {
			public void run() {

				prepareCursorData();

				prepareCollections();

				loadingHandler.sendEmptyMessage(0);
			};
		}.start();
	}

	private void prepareCursorData() {
		helper.open();
		if (isUnitTest) {
			cursor = helper.getCursorDataByUnitId(unitId);
			// 单元测试模式的最后一个变量的初始化在这里
			mTestCount = cursor.getCount();
		} else {
			cursor = helper.getCursorDataByType(mTestType);
		}
		maxNum = cursor.getCount();

		helper.close();
	}

	private void prepareCollections() {
		if (isNewTest == true) {
			details = new int[mTestCount];
			checkSet = new TreeSet<Integer>();
			nowPosition = 0;
			return;
		}
		details = helper.getDetailsFromFile(isUnitTest, mTestCount);
		checkSet = helper.getCheckedSet(details, mFinishedCount);

		nowPosition = (mFinishedCount - 1) > 0 ? (mFinishedCount - 1) : 0;
	}
	
	private void freshState() {
		testProgressShow.setText("进度：" + mFinishedCount + " / " + mTestCount);
		if ((nowPosition == mTestCount - 1) && (!canChange)) {
			nextWord.setText(R.string.tip_finish);
			canChange = true;
		} else if (canChange) {
			nextWord.setText(R.string.test_next_one);
			canChange = false;
		}
	}

	private void initComponents() {
		backToMenu = (Button) findViewById(R.id.starttest_btn_back);
		nextWord = (Button) findViewById(R.id.starttest_btn_next_one);
		previousWord = (Button) findViewById(R.id.starttest_previous_one);
		testProgressShow = (TextView) findViewById(R.id.starttest_progress);
		displayExplain = (EditText) findViewById(R.id.starttest_et_hint);
		wordInput = (EditText) findViewById(R.id.starttest_input);

		nextWord.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				String input = wordInput.getText().toString().trim();
				checkAndHandleInput(input);
				nowPosition = nowPosition + 1 > mTestCount - 1 ? mTestCount - 1
						: nowPosition + 1;
				if (mFinishedCount >= mTestCount) {
					saveAndJump();
				}
				prepareWord(nowPosition);
			}
		});

		previousWord.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				nowPosition = nowPosition - 1 > 0 ? nowPosition - 1 : 0;
				prepareWord(nowPosition);
			}
		});

		backToMenu.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				saveAndQuit();
			}
		});
	}

	private void checkAndHandleInput(String input) {
		finishTimeInMillis = System.currentTimeMillis();
		allTimeInMillis += (finishTimeInMillis - startTimeInMillis);
		boolean isCorrect = false;
		for (String nowWord : nowWords) {
			Log.d(TAG, "Words " + nowWord + " Word's Length" + nowWord.length());
			if (nowWord.equals(input)) {
				isCorrect = true;
				break;
			}
		}
		Log.d(TAG, "Input " + input + " Input's Length " + input.length() + " isCorrect " + isCorrect);
		details[nowPosition] = helper.getWrappedId(details[nowPosition],
				isCorrect);
	}

	private void saveAndQuit() {
		boolean isAllReady = helper.saveIntoFile(details, isUnitTest);
		if (isAllReady) {
			saveControlParam();
		}
		
		Toast.makeText(CompletionTest.this, R.string.tip_progressSaved,
				Toast.LENGTH_SHORT).show();
		finish();
	}

	private void saveControlParam() {
		SharedPreferences pref = getSharedPreferences(CommandList.PREF_NAME,
				MODE_PRIVATE);
		SharedPreferences.Editor editor = pref.edit();

		if (isUnitTest) {
			helper.saveUnitTestParam(editor, true, unitId, mFinishedCount, allTimeInMillis);
		} else {
			helper.saveOptionalTestParam(editor, true, mTestCount,
					mFinishedCount, mTestType, allTimeInMillis);
		}
	}
	
	private void saveAndJump(){
		progressDialog.setMessage(getText(R.string.tip_saving));
		progressDialog.show();
		new Thread(){
			public void run() {
				long currentTime = System.currentTimeMillis();
				int wrongCounts = helper.updateResult(details, currentTime);
				clearParams();
				sendIntent = new Intent();
				sendIntent.setClass(CompletionTest.this, ResultShow.class);
				sendIntent.putExtra(CommandList.LATELY_ACCESS, currentTime);
				sendIntent.putExtra(CommandList.WRONG_COUNTS, wrongCounts);
				sendIntent.putExtra(CommandList.ALL_COUNTS, mTestCount);
				sendIntent.putExtra(CommandList.ALL_TIME, allTimeInMillis);
				savingHandler.sendEmptyMessage(0);
			};
		}.start();
	}
	
	private void clearParams(){
		SharedPreferences pref = getSharedPreferences(CommandList.PREF_NAME,
				MODE_PRIVATE);
		SharedPreferences.Editor editor = pref.edit();
		if(isUnitTest){
			helper.clearUnitParams(editor, true);
		}else{
			helper.clearOptionalParam(editor, true);
		}
	}
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if(keyCode == KeyEvent.KEYCODE_BACK){
			saveAndQuit();
		}
		return super.onKeyDown(keyCode, event);
	}
}